//
//  LocationsSearchResultsViewModel.swift
//  SwiftWeather
//
//  Created by shen on 2023/8/28.
//

import Foundation
import Combine

final class LocationsSearchResultsViewModel {
    // MARK: Properties

    var numberOfResults: Int {
        cities.count
    }

    var updateResultsPublisher: AnyPublisher<Void, Never> {
        updateResultsSubject.eraseToAnyPublisher()
    }

    var coordinatorPublisher: AnyPublisher<City, Never> {
        coordinatorSubject.eraseToAnyPublisher()
    }

    var locationSelectionSubject: PassthroughSubject<IndexPath, Never> = PassthroughSubject()

    var clearResultsSubject: PassthroughSubject<Void, Never> = PassthroughSubject()

    private var updateResultsSubject = PassthroughSubject<Void, Never>()

    private var coordinatorSubject = PassthroughSubject<City, Never>()

    private var cancellables = Set<AnyCancellable>()

    private var cities = [City]()

    // MARK: - Initialization

    init() {
        setBindings()
    }

    // MARK: - Methods

    func titleForLocation(at indexPath: IndexPath) -> String {
        let city = cities[indexPath.row]

        guard
            let cityName = city.name,
            let regionName = city.region,
            let countryName = city.country
        else { return "" }

        if cityName == regionName {
            return "\(cityName), \(countryName)"
        } else {
            return "\(cityName), \(regionName), \(countryName)"
        }
    }

    func updateResults(with cities: [City]) {
        self.cities = cities
        updateResultsSubject.send()
    }
}

// MARK: - Private methods

private extension LocationsSearchResultsViewModel {
    func setBindings() {
        clearResultsSubject
            .sink { [weak self] in
                self?.updateResults(with: [])
            }
            .store(in: &cancellables)

        locationSelectionSubject
            .compactMap { [weak self] indexPath in
                self?.cities[indexPath.row]
            }
            .sink { [weak self] city in
                self?.coordinatorSubject.send(city)
            }
            .store(in: &cancellables)
    }
}
